﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Clinica_Frba
{
    public partial class TurnoForm : Form
    {
        Conexion sqlCon = Conexion.getInstance();
        Utility util = Utility.getInstance();
        TimeSpan treintaMinutos = new TimeSpan(0, 0, 30, 0, 0);
        int idMed;
        decimal idAfiliado;
        int idAgenda;
        int idDia;
        DateTime fechaInicio;
        DateTime fechaFin;
        TimeSpan horaInicio;
        TimeSpan horaFin;
        string[] tablaIdDias = { "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo" };
        string[] tablaEnDias = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
        bool agendaClick = false;
        bool esAfiliado = false;

        public TurnoForm()
        {
            InitializeComponent();
        }

        private void TurnoForm_Load(object sender, EventArgs e)
        {
            SqlDataReader reader;

            this.Text = "Pedir Turno";

            // Fecha de atencion
            fechaAtencion.Format = DateTimePickerFormat.Custom;
            fechaAtencion.CustomFormat = " ";
            fechaAtencion.Enabled = false;

            // Parametros grid
            dGridHorarios.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dGridHorarios.MultiSelect = false;

            // Obtener afiliado
            reader = sqlCon.execQuery("SELECT Id_Paciente, (Paciente_Nombre + ' ' + Paciente_Apellido) nom FROM b_sharp.Pacientes WHERE Usuario = '" + util.getUserName() + "';");
            if (reader.Read())
            {
                idAfiliado = reader.GetInt32(0);
                afiliadoBox.Text = reader.GetString(1);
                esAfiliado = true;
            }
            else
            {   // Habilitar la busqueda de afiliado
                afiliadoButton.Visible = true;
                idAfiliado = -1;
            }
        }

        private void loadEspecialidades()
        {
            string select;
            SqlDataAdapter adapter;
            DataTable table = new DataTable();

            select = "SELECT es.Cod_Especialidad, Esp_Descripcion " +
                         " FROM b_sharp.Especialidades es " +
                         " JOIN b_sharp.EspecialidadMedico em ON es.Cod_Especialidad = em.Cod_Especialidad " +
                         " WHERE id_medico = " + idMed + ";";

            //Llenar especialidades
            adapter = sqlCon.execQueryGrid(select);
            adapter.Fill(table);

            especialidades.DataSource = table;
            especialidades.DisplayMember = "Esp_Descripcion";
            especialidades.ValueMember = "Cod_Especialidad";
            especialidades.SelectionMode = SelectionMode.One;
        }

        private void buscarMed_Click(object sender, EventArgs e)
        {
            SqlDataReader reader;
            ListaProfesionales medicoForm = new ListaProfesionales();

            idMed = medicoForm.searchMedico();

            reader = sqlCon.execQuery("SELECT (Medico_Nombre + ' ' + Medico_Apellido) nom " + 
                                      " FROM b_sharp.Medicos where id_medico = " + idMed + ";");
            if (reader.Read())
            {
                medico.Text = reader.GetString(0);
                buttonAgenda.Visible = true;
                loadEspecialidades();
            }
        }

        private void buttonAgenda_Click(object sender, EventArgs e)
        {
            SqlDataReader reader;

            BuscarAgenda agendaForm = new BuscarAgenda();

            if (agendaForm.searchAgenda(idMed, out idAgenda, out idDia))
            {
                reader = sqlCon.execQuery("SELECT fechaInicio, fechaFin, horaInicio, horaFin " + 
                                          " FROM b_sharp.AgendaProfesional ap " + 
                                          " JOIN b_sharp.AgendaProfHorarios ah ON ap.id_agenda = ah.id_agenda AND ap.id_medico = ah.id_medico" + 
                                          " WHERE ah.cod_dia = " + idDia +
                                          "   AND ap.id_agenda = " + idAgenda + 
                                          "   AND ap.id_medico = " + idMed + ";");
                if (reader.Read())
                {
                    agenda.Text = reader.GetDateTime(0).Date.ToString("dd/MM/yyyy") + " - " + reader.GetDateTime(1).Date.ToString("dd/MM/yyyy");
                    horario.Text = Convert.ToString(reader.GetValue(2)) + " - " + Convert.ToString(reader.GetValue(3));
                    diaAgenda.Text = tablaIdDias[idDia - 1];
                    fechaInicio = reader.GetDateTime(0);
                    fechaFin = reader.GetDateTime(1);
                    horaInicio = reader.GetTimeSpan(2);
                    horaFin = reader.GetTimeSpan(3);

                    agendaClick = true;
                    fechaAtencion.Enabled = true;
                    fechaAtencion.MinDate = fechaInicio;
                    fechaAtencion.MaxDate = fechaFin;
                    agendaClick = false;

                    buttonVerTurnos.Enabled = true;
                }
            }
        }

        private void fechaAtencion_ValueChanged(object sender, EventArgs e)
        {
            if (agendaClick)
                return;

            while (dGridHorarios.Rows.Count > 0)
                dGridHorarios.Rows.RemoveAt(0);
        }

        private void mostrarHorariosDisponibles()
        {
            SqlDataReader reader;
            DataTable table = new DataTable();
            string consulta;
            int i = 0;
            string month;
            string day;
            
            List<TimeSpan> listHorarios = crearListaHorarios();

            if (fechaAtencion.Value.Month < 10)
                month = "0" + Convert.ToString(fechaAtencion.Value.Month);
            else
                month = Convert.ToString(fechaAtencion.Value.Month);

            if (fechaAtencion.Value.Day < 10)
                day = "0" + Convert.ToString(fechaAtencion.Value.Day);
            else
                day = Convert.ToString(fechaAtencion.Value.Day);

            // Obtener turnos actuales
            consulta = "SELECT CONVERT(time,Turno_Fecha) horaInicio  FROM b_sharp.Turnos tu " + 
                       " WHERE CONVERT(date,Turno_Fecha) = '" + fechaAtencion.Value.Year + month + day + "' " +
                       " AND CONVERT(time,Turno_Fecha) >= '" + horaInicio.ToString() + ".0000000" + "' " +
                       " AND CONVERT(time,Turno_Fecha) < '" + horaFin.ToString() + ".0000000" + "' " +   
                       " AND Medico_ID = " + idMed + 
                       " AND id_agenda = " + idAgenda + 
                       " AND not exists (SELECT 1 FROM b_sharp.Cancelaciones ca WHERE tu.Turno_Numero = ca.Turno_Numero);";

            reader = sqlCon.execQuery(consulta);
            
            // Eliminar turnos actuales de la pantalla de seleccion
            while (reader.Read())
            {
                i = listHorarios.IndexOf(reader.GetTimeSpan(0));
                
                if (i != -1)
                    listHorarios.RemoveAt(i);
            }

            if (listHorarios.Count > 0)
                fillGridHorarios(listHorarios);
            else
                MessageBox.Show("No hay turnos disponibles para la fecha seleccionada", "Turno");
        }

        private void fillGridHorarios(List<TimeSpan> list)
        {
            DataTable table = new DataTable();
            DataRow row;

            table.Columns.Add("horaInicio");
            table.Columns[0].DataType = list[0].GetType();
            table.Columns.Add("horaFin");
            table.Columns[1].DataType = list[0].GetType();

            foreach (TimeSpan time in list)
            {
                row = table.NewRow();
                row[0] = time;
                row[1] = time.Add(treintaMinutos);

                table.Rows.Add(row);
            }

            dGridHorarios.DataSource = table;
        }

        private List<TimeSpan> crearListaHorarios()
        {
            List<TimeSpan> list = new List<TimeSpan>();
            TimeSpan horaInicial = horaInicio;

            while (horaInicial.ToString() != horaFin.ToString())
            {
                list.Add(horaInicial);
                horaInicial = horaInicial.Add(treintaMinutos);
            }

            return list;
        }

        private void limpiar_Click(object sender, EventArgs e)
        {
            //Limpiar grid
            while (dGridHorarios.Rows.Count > 0)
                dGridHorarios.Rows.RemoveAt(0);

            //Limpiar especialidades
            if (especialidades.Items.Count > 0)
                especialidades.DataSource = new DataTable();

            //Limpiar fecha
            fechaAtencion.Format = DateTimePickerFormat.Custom;
            fechaAtencion.CustomFormat = " ";
            fechaAtencion.Enabled = false;
            
            //Sacar botones
            buttonAgenda.Visible = false;
            buttonVerTurnos.Enabled = false;

            //Limpiar filtros
            foreach (Control control in this.Controls)
            {
                if (control.GetType().ToString() == "System.Windows.Forms.GroupBox")
                    foreach (Control grpControl in ((System.Windows.Forms.GroupBox)control).Controls)
                    {
                        if (esAfiliado)
                        {
                            if (((grpControl.GetType().ToString() == "System.Windows.Forms.ComboBox") | (grpControl.GetType().ToString() == "System.Windows.Forms.TextBox")) && grpControl.Name != "afiliadoBox")
                            {
                                grpControl.ResetText();
                            }
                        }
                        else
                        {
                            if ((grpControl.GetType().ToString() == "System.Windows.Forms.ComboBox") | (grpControl.GetType().ToString() == "System.Windows.Forms.TextBox"))
                            {
                                grpControl.ResetText();
                            }

                        }
                    }
            }
        }

        private void confirmar_Click(object sender, EventArgs e)
        {
            TimeSpan horaTurno;
            decimal idEsp;
            DateTime turnoFecha;
            string insert, message = "";
            SqlCommand cmd;

            if (dGridHorarios.Rows.Count == 0)
            {
                message = "Seleccione un horario de atencion\n";
            }

            if (idAfiliado == -1)
            {
                message += "Seleccione un afiliado\n";
            }

            if (message.Length > 0)
            {
                MessageBox.Show(message, "Error");
                return;
            }

            horaTurno = (TimeSpan)dGridHorarios.SelectedRows[0].Cells[0].Value;
            idEsp = (decimal)especialidades.SelectedValue;

            turnoFecha = new DateTime(fechaAtencion.Value.Date.Year, fechaAtencion.Value.Date.Month, fechaAtencion.Value.Date.Day, 0, 0, 0, 0);
            turnoFecha = turnoFecha.Add(horaTurno);
            
            insert = "INSERT INTO b_sharp.Turnos (Paciente_ID, Medico_ID, id_agenda, Turno_Fecha, Medico_Especialidad) " + 
                     " VALUES (@idAfiliado, @idMed, @idAgenda, @turnoFecha, @espCod);";

            cmd = new SqlCommand(insert,sqlCon.openCon());
            cmd.Parameters.AddWithValue("@idAfiliado",idAfiliado);
            cmd.Parameters.AddWithValue("@idMed",idMed);
            cmd.Parameters.AddWithValue("@idAgenda",idAgenda);
            cmd.Parameters.AddWithValue("@turnoFecha",turnoFecha);
            cmd.Parameters.AddWithValue("@espCod",idEsp);
            cmd.ExecuteNonQuery();

            MessageBox.Show("Turno generado correctamente", "Turno");

            this.Close();
        }

        private void afiliadoButton_Click(object sender, EventArgs e)
        {
            SqlDataReader reader;
            BuscarAfiliadoForm busquedaAfiliado = new BuscarAfiliadoForm();
            
            idAfiliado = busquedaAfiliado.searchAfiliado();

            if (idAfiliado == -1)
                return;

            reader = sqlCon.execQuery("SELECT (Paciente_Nombre + ' ' + Paciente_Apellido) nom " +
                                      " FROM b_sharp.Pacientes where Id_Paciente = " + idAfiliado + ";");
            if (reader.Read())
            {
                afiliadoBox.Text = reader.GetString(0);
            }
        }

        private void buttonVerTurnos_Click(object sender, EventArgs e)
        {
            int i = 1;

            if (fechaAtencion.Format != DateTimePickerFormat.Short)
            {
                MessageBox.Show("Seleccione una Fecha", "Error");
                return;
            }

            foreach (string dia in tablaEnDias)
            {
                if (Convert.ToString(fechaAtencion.Value.DayOfWeek) == dia)
                    break;
                i++;
            }

            if (i != idDia)
                MessageBox.Show("La fecha debe ser un " + diaAgenda.Text, "Error");
            else
                mostrarHorariosDisponibles();
        }

        private void fechaAtencion_CloseUp(object sender, EventArgs e)
        {
            fechaAtencion.Format = DateTimePickerFormat.Short;
        }
    }
}
